const { randomBytes, pbkdf2 }  = require('node:crypto');

// const derive    = function(password, salt, iterations, keyLength, digest, encoding) {
//     return new Promise((resolve, reject) => {
//         pbkdf2(
//             password, salt, iterations, keyLength, digest, (error, derivedKey) => {
//                 if (error) {
//                     reject(error);
//                 } else {
//                     resolve(derivedKey.toString(encoding));
//                 }
//             }
//         );
//     });
// };

const encrypt   = async function(password) {
    var salt        = randomBytes(16).toString('hex');
    var digest      = 'sha512';
    var keyLength   = 64;
    var iterations  = 100000;
    var secret      = await new Promise((resolve, reject) => {
        pbkdf2(
            password, salt, iterations, keyLength, digest, 
            (error, derivedKey) => {
                if (error) {
                    reject(error);
                } else {
                    resolve(derivedKey.toString('hex'));
                }
            }
        );
    });

    return `PBKDF2|${salt}|${iterations}|${keyLength}|${digest}|${secret}`;
};

const verify    = async function(plain, cipher) {
    var parts   = cipher.split("|");
    if (parts.length === 6 && parts[0]  === "PBKDF2") {
        var salt        = parts[1];
        var iterations  = Number.parseInt(parts[2]);
        var keyLength   = Number.parseInt(parts[3])
        var digest      = parts[4];
        var secret      = parts[5];

        return await new Promise((resolve, reject) => {
            pbkdf2(
                plain, salt, iterations, keyLength, digest, 
                (error, derivedKey) => {
                    if (error) {
                        reject(error);
                    } else {
                        resolve(derivedKey.toString('hex') === secret);
                    }
                }
            );
        });
    }

    return false;
};

module.exports  = { encrypt, verify };
